

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import View.*;

/**
 * Servlet to manage most operations in the webshop, ranging from menu rendering to item controlling
 * to check out managing.
 */
@WebServlet("/items/*")
public class MasterServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
   
    /**
     * Autp-generated constructor
     */
    public MasterServlet() {
        super();
    }

	/*
	 * Checks from where the request is being sent with the hidden field.
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String id = request.getParameter("id");
		String hidden = request.getParameter("hidden");
		String url = "/index.jsp";
		String path = request.getPathInfo();
		String path2 = request.getRequestURL().toString();
		System.out.println("hidden " + hidden);
		if (hidden == null && id == null) { // Happens when a menu is clicked, presenting what's in the category and it's items.
			String lastSubMenu = getMostSubMenu(path);
			request.setAttribute("parentPath", path);
			ArrayList<CategoryView> subCategory = Controller.getSubCategory(lastSubMenu);
			request.setAttribute("content", subCategory);
			request.setAttribute("items", Controller.getItemsByCategoryName(lastSubMenu));
			
			url = "/content.jsp"; // Redirect to content page.
			
		} else if (id != null){ // When an item is requested
			int itemId = Integer.parseInt(id);
			ItemView item = Controller.getItemById(itemId);
			String tempAmount = request.getParameter("amount");
			int amount = 1;
			if (tempAmount != null)
				amount = Integer.parseInt(tempAmount);
			
			String category = "No category";
			if (item != null) {
				category = Controller.getCategoryNameByNr(item.getCategory());
			}
			if (hidden != null) {
				if (hidden.equals("addToCart")) {
					addToCart(request, itemId, amount);
				}
			}
			request.setAttribute("category", category);
			request.setAttribute("item", item);
			url = "/item.jsp?=" + itemId;
		} else if (hidden.equals("checkout")) { // When the checkout button is pressed in the shopping cart...
			url = "/checkout.jsp"; // ... redirect to the checkout page.
		} else if (hidden.equals("updateCheckout")) { // When the update button is clicked in the checkout page
			Enumeration<String> allAttributes = request.getParameterNames();
			Pattern pattern = Pattern.compile("amount_[0-9]+");
			ArrayList<OrderItemView> cart = (ArrayList<OrderItemView>) request.getSession().getAttribute("cart");
			while (allAttributes.hasMoreElements()) {
				String attribute = allAttributes.nextElement();
				Matcher m = pattern.matcher(attribute);
				if (m.matches()) {
					int amount = Integer.parseInt(request.getParameter(attribute));
					int parsedItemId = Integer.parseInt(attribute.substring("amount_".length()));
					for (int i = 0; i < cart.size(); i++) {
						if (cart.get(i).getItem().getItemId() == parsedItemId) {
							cart.get(i).setAmount(amount);
							break;
						}
					}
				}
			}
			cart = Controller.updateCart(cart);
			if (cart.size() == 0) {
				request.getSession().setAttribute("cart", null);
				url = "/index.jsp"; // Redirect to index if cart is empty after update.
			} else {
				request.getSession().setAttribute("cart", cart);
				url = "/checkout.jsp"; // Redirect to checkout after update is finished.
			}
		} else if (hidden.equals("doneAndOrder")) { // When the order button is clicked, place the order if logged in, otherwise prompted to log in.
			UserView user = (UserView) request.getSession().getAttribute("user");
			if (user != null) {
				// Place order
				ArrayList<OrderItemView> cart = (ArrayList<OrderItemView>) request.getSession().getAttribute("cart");
				url = "/index.jsp";
				if (cart != null) {
					url = "/checkout.jsp";
					if (Controller.placeAnOrder(cart, user)) {
						request.getSession().setAttribute("cart", null);
						url = "/user/profile.jsp";
					}
				}
			} else {	// If no user then redirect to login.jsp
				url = "/login.jsp";
			}
		} else if (hidden.equals("clearCart")) { // Clear the cart when the clear button is clicked in the shopping cart.
			request.getSession().setAttribute("cart", null);
			System.out.println("clear cart " + path2);
			url = "/index.jsp";
		} else if (hidden.matches("orderId_[0-9]+")) { // Packs the order if the hidden field is matching one of the order numbers.
			String stringOrderId = hidden.substring("orderId_".length());
			int orderId = Integer.parseInt(stringOrderId);
			Controller.packOrder(orderId);
			url = "/packingpage.jsp";
		}
		RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url);
		dispatcher.forward(request, response); // Forwards to the specified url.
	}

	/*
	 * Requests the doGet() method.
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

	/*
	 * Method to get the lowest submenu in the menu-hierarchy.
	 * @param url - What url to be looked through.
	 * @return - New url with the lowest submenu.
	 */
	private String getMostSubMenu(String url) {
		String newUrl = url;
		if (url.lastIndexOf('/')+1 == url.length()) {
			newUrl = url.substring(0, url.lastIndexOf('/'));
		}
		int position = newUrl.lastIndexOf('/') + 1;
		newUrl = newUrl.substring(position);
		return newUrl;
	}
	
	/*
	 * Method to add an item to the shopping cart in the current session.
	 * @param request - The HttpServletRequest object
	 * @param id - ItemId to  be placed in the cart
	 * @param amount - How many of the item that will be placed in the cart.
	 */
	private void addToCart(HttpServletRequest request, int id, int amount) {
		ArrayList<OrderItemView> cart = (ArrayList<OrderItemView>) request.getSession().getAttribute("cart");
		if (cart == null) {
			cart = new ArrayList<OrderItemView>();
		}
		OrderItemView oiv = Controller.getOrderItem(id, amount);
		Controller.checkCart(cart, oiv);
		request.getSession().setAttribute("cart", cart);
	}
	
//	private String getUrlWithParameters(HttpServletRequest request) {
//		Enumeration<String> parameters = request.getParameterNames();
//		if (parameters.hasMoreElements()) {
//			String url = "?";
//			String parameterName = parameters.nextElement();
//			String attribute = (String) request.getAttribute(parameterName);
//			url = url + parameterName + "=" + attribute;
//			while (parameters.hasMoreElements()) {
//				url = url + "&";
//				parameterName = parameters.nextElement();
//				attribute = (String) request.getAttribute(parameterName);
//				url = url + parameterName + "=" + attribute;
//			}
//			return url;
//		}
//		return "";
//	}
	
}
